﻿#region << 版 本 注 释 >>
/*
     * ========================================================================
     * Copyright Notice  2010-2021 TideBuy.com All rights reserved .
     * ========================================================================
     * 机器名称：DESKTOP-VJFB8FV 
     * 文件名：  MainWindowViewModel 
     * 版本号：  V1.0.0.0 
     * 创建人：  徐一贺 
     * 创建时间： 2021/3/6 12:57:05 
     * 描述    :
     * =====================================================================
     * 修改时间：2021/3/6 12:57:05 
     * 修改人  ： 徐一贺
     * 版本号  ： V1.0.0.0 
     * 描述    ：
*/
#endregion
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using AluminumCoilParallelSurfaceWarehouse;
using CoilIntelStorage.Models;
using CoilIntelStorage.Utils;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Unity;

namespace CoilIntelStorage.ViewModels
{
    /// <summary>
    /// 主窗体ViewModel
    /// </summary>
    class MainWindowViewModel : BindableBase
    {
        StockIn stock = null;
        //创建
        public DelegateCommand CreateTaskCommand { get; set; }
        //刷新数据源
        public DelegateCommand RefreshCommandListCommand { get; set; }
        //任务队列线程
        Thread executedTaskQueueThread = null;
        /// <summary>
        /// 打开新建窗体
        /// </summary>
        /// <param name="parameter"></param>
        private void CreateTask(object parameter)
        {
            stock.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            stock.ShowDialog();
        }
        /// <summary>
        /// 添加Window属性
        /// </summary>
        private MainWindow window { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        public MainWindowViewModel(object window)
        {
            this.window = (MainWindow)window;
            stock = new StockIn();
            // 让CreateTask和CreateTaskCommand关联起来
            CreateTaskCommand = new DelegateCommand(() =>
            {
                CreateTask(null);
            });
            // 让AddInStock和RefreshCommandList关联起来
            RefreshCommandListCommand = new DelegateCommand(() =>
            {
                AddInStock("Refresh command list");
            });
            stock.Send += AddInStock;
            // 绑定任务队列数据源
            BindTaskQueue();
            // 开启线程，启动自动执行任务方法。
            executedTaskQueueThread = new Thread(ExecutedTaskQueue)
            {
                IsBackground = true//这个是把我们这个线程放到后台线程里面执行
            };
            //执行线程
            executedTaskQueueThread.Start();
            DisplayCraneThreadInfo = "设置吊车线程为后台执行模式，\r\n开启吊车收发线程。";
        }
        //任务队列
        private List<TaskQueue> taskQueueList;
        //任务队列
        public List<TaskQueue> TaskQueueList
        {
            get { return taskQueueList; }
            set
            {
                this.taskQueueList = value;
                this.RaisePropertyChanged("TaskQueueList");
            }
        }
        //指令队列
        private List<Instruction> instructionList;
        //指令队列
        public List<Instruction> InstructionList
        {
            get { return instructionList; }
            set
            {
                this.instructionList = value;
                this.RaisePropertyChanged("InstructionList");
            }
        }
        //吊车线程信息
        private string displayCraneThreadInfo;
        //吊车线程信息
        public string DisplayCraneThreadInfo {
            get { return displayCraneThreadInfo; }
            set
            {
                this.displayCraneThreadInfo = value;
                this.RaisePropertyChanged("DisplayCraneThreadInfo");
            }
        }



        /// <summary>
        /// 对任务列表绑定数据源
        /// </summary>
        private void BindTaskQueue()
        {
            //加载任务列表
            DataTable dataTable = DbHelper.GetTable("SELECT * FROM task_queue WHERE status in (1,2)  ORDER BY build_time");
            List<TaskQueue> taskQueueListFromDataBase = new List<TaskQueue>();
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                TaskQueue taskQueue = new TaskQueue();
                DataRow dataRow = dataTable.Rows[i];
                if (dataRow["id"] != DBNull.Value)
                {
                    taskQueue.Id = Convert.ToInt32(dataRow["id"]);
                }
                if (dataRow["type"] != DBNull.Value)
                {
                    taskQueue.Type = Convert.ToInt32(dataRow["type"]);
                    if (taskQueue.Type == 1)
                    {
                        taskQueue.TypeStr = "入库";
                    }
                    else if (taskQueue.Type == 2)
                    {
                        taskQueue.TypeStr = "出库";
                    }
                    else if (taskQueue.Type == 3)
                    {
                        taskQueue.TypeStr = "挪库";
                    }
                }
                if (dataRow["start_point"] != DBNull.Value)
                {
                    taskQueue.Start_point = dataRow["start_point"].ToString();
                }
                if (dataRow["end_point"] != DBNull.Value)
                {
                    taskQueue.End_point = dataRow["end_point"].ToString();
                }
                if (dataRow["build_time"] != DBNull.Value)
                {
                    taskQueue.Build_time = Convert.ToDateTime(dataRow["build_time"]);
                }
                if (dataRow["start_time"] != DBNull.Value)
                {
                    taskQueue.Start_time = Convert.ToDateTime(dataRow["start_time"]);
                }
                if (dataRow["end_time"] != DBNull.Value)
                {
                    taskQueue.End_time = Convert.ToDateTime(dataRow["end_time"]);
                }
                if (dataRow["status"] != DBNull.Value)
                {
                    taskQueue.Status = Convert.ToInt32(dataRow["status"]);
                }
                if (dataRow["goods_code"] != DBNull.Value)
                {
                    taskQueue.Goods_code = dataRow["goods_code"].ToString();
                }
                taskQueue.OrderNo = i + 1;

                taskQueueListFromDataBase.Add(taskQueue);

            }
            this.TaskQueueList = taskQueueListFromDataBase;
        }

        /// <summary>
        /// 刷新
        /// </summary>
        /// <param name="message"></param>
        public void AddInStock(string message)
        {
            if (message.Equals("Refresh command list"))
            {
                BindTaskQueue();
            }
        }

        /// <summary>
        /// 执行任务队列方法
        /// </summary>
        private void ExecutedTaskQueue()
        {
            while (executedTaskQueueThread.IsAlive)
            {
                if (TaskQueueList.Count > 0)
                {
                    TaskQueue taskQueue = TaskQueueList[0];
                    taskQueue.Start_time = DateTime.Now;
                    taskQueue.Status = 2;
                    String sql = "UPDATE task_queue SET start_time = @start_time,status =  @status WHERE id = @id;";
                    SqlParameter[] sqlParameters = new SqlParameter[] {
                    new SqlParameter("@id",taskQueue.Id),
                    new SqlParameter("@start_time",taskQueue.Start_time),
                    new SqlParameter("@status",taskQueue.Status),
                    };
                    int n = DbHelper.ExcuteSQL(sql, sqlParameters);
                    if (n > 0)
                    {
                        //刷新命令队列数据源
                        GetInstructionListByTaskId(taskQueue.Id);
                        //创建发送给吊车去搬运的指令
                        ElectronicMessage toCraneDoCarryElectronicMessage = new ElectronicMessage();
                        //入库
                        if (taskQueue.Type == 1)
                        {
                            DisplayCraneThreadInfo += "开始入库";
                            DisplayCraneThreadInfo += "\r\n标识UI界面状态";
                            window.ChangePositionStatusByOper("开始入库", taskQueue.Start_point, taskQueue.End_point);
                            toCraneDoCarryElectronicMessage.Type = 1;
                            toCraneDoCarryElectronicMessage.Instructions = "吊车搬运指令";
                            if (taskQueue.Start_point.Equals("1#"))
                            {
                                toCraneDoCarryElectronicMessage.EntranceAndExit = 1;
                            }
                            else if (taskQueue.Start_point.Equals("2#"))
                            {
                                toCraneDoCarryElectronicMessage.EntranceAndExit = 2;
                            }
                            toCraneDoCarryElectronicMessage.Head = 102;
                            toCraneDoCarryElectronicMessage.Code = taskQueue.Goods_code.Replace("-", "");
                            toCraneDoCarryElectronicMessage.SendOrAnswer = "01";
                            //向吊车发送搬运，并获得搬运应答
                            ElectronicMessage fromCraneAnswerElectronicMessage = SendingCraneElectronicMessage(toCraneDoCarryElectronicMessage, taskQueue);
                            Thread.Sleep(5000);
                            DisplayCraneThreadInfo += "\r\n更新任务状态为完成";
                            //更新任务状态为完成
                            String sql5 = "UPDATE task_queue SET end_time = @end_time,status =  @status WHERE id = @id;";
                            SqlParameter[] sqlParameters5 = new SqlParameter[] {
                                        new SqlParameter("@id",taskQueue.Id),
                                        new SqlParameter("@end_time",DateTime.Now),
                                        new SqlParameter("@status",3),
                                        };
                            DbHelper.ExcuteSQL(sql5, sqlParameters5);
                            Thread.Sleep(5000);
                            DisplayCraneThreadInfo += "\r\n设置数据库中库位状态";
                            Thread.Sleep(5000);
                            DisplayCraneThreadInfo += "\r\n同步UI界面状态";
                            window.ChangePositionStatusByOper("入库结束", taskQueue.Start_point, taskQueue.End_point);
                            //更新库位状态为满
                            
                            String sql6 = "UPDATE stock SET status = @status WHERE name = @name;";
                            SqlParameter[] sqlParameters6 = new SqlParameter[] {
                                        new SqlParameter("@name",taskQueue.End_point),
                                        new SqlParameter("@status",1),
                                        };
                            if (DbHelper.ExcuteSQL(sql6, sqlParameters6) > 0)
                            {
                                BindTaskQueue();
                                InstructionList = new List<Instruction>();
                            }
                        }
                        //出库
                        else if (taskQueue.Type == 2)
                        {
                            toCraneDoCarryElectronicMessage.Type = 2;

                        }
                        //挪库
                        else if (taskQueue.Type == 3)
                        {
                            toCraneDoCarryElectronicMessage.Type = 3;
                        }
                    }
                }
                Thread.Sleep(100);
            }
        }

        /// <summary>
        /// 发送报文并返回应答报文
        /// </summary>
        /// <param name="electronicMessage">报文内容</param>
        /// <param name="taskQueue">任务</param>
        /// <returns>报文</returns>
        private ElectronicMessage SendingCraneElectronicMessage(ElectronicMessage electronicMessage, TaskQueue taskQueue)
        {
            Thread.Sleep(5000);
            ElectronicMessage result = null;
            Instruction instruction = new Instruction();
            ObjectCloneUtil.Clone<Instruction>(InstructionList[0], ref instruction);
            instruction.Socket_code = electronicMessage.Head.ToString() +
                electronicMessage.EntranceAndExit.ToString() +
                taskQueue.End_point.Replace("-", "") +
                electronicMessage.Code +
                electronicMessage.SendOrAnswer;
            instruction.Content = electronicMessage.Instructions;
            DataSet ds = DbHelper.GetDataSet("SELECT * FROM instruction WHERE task_id = " + taskQueue.Id + " AND socket_code = '" + instruction.Socket_code + "'");
            int sendResultCount = 0;
            if (ds.Tables[0].Rows.Count == 0)
            {
                //把发送的报文内容入库
                string sql = "INSERT INTO instruction(start_point,end_point,send_time,socket_code,content,task_id)VALUES(@start_point,@end_point,@send_time,@socket_code,@content,@task_id);";
                SqlParameter[] sqlParameters = new SqlParameter[] {
                    new SqlParameter("@start_point",instruction.Start_point),
                    new SqlParameter("@end_point",instruction.End_point),
                    new SqlParameter("@send_time",DateTime.Now),
                    new SqlParameter("@socket_code",instruction.Socket_code),
                    new SqlParameter("@content",instruction.Content),
                    new SqlParameter("@task_id",instruction.Task_id)};
                sendResultCount = DbHelper.ExcuteSQL(sql, sqlParameters);
            }
            if (ds.Tables[0].Rows.Count > 0 || sendResultCount > 0)
            {
                DisplayCraneThreadInfo += "\r\n给吊车发送搬运指令";
                GetInstructionListByTaskId(taskQueue.Id);
                Thread.Sleep(5000);
                //获得吊车返回指令（模拟）
                result = new ElectronicMessage();
                result.Head = 102;
                result.Type = electronicMessage.Type;
                result.Instructions = "吊车搬运指令应答";
                result.EntranceAndExit = electronicMessage.EntranceAndExit;
                result.Position = electronicMessage.Position;
                result.Code = electronicMessage.Code;
                result.SendOrAnswer = "02";
                DataSet ds2 = DbHelper.GetDataSet("SELECT * FROM instruction WHERE task_id = " + taskQueue.Id + " AND socket_code = '" + result.Head.ToString() +
                                                                        result.EntranceAndExit.ToString() +
                                                                        taskQueue.End_point.Replace("-", "") +
                                                                        result.Code +
                                                                        result.SendOrAnswer + "'");
                if (ds2.Tables[0].Rows.Count == 0)
                {
                    Thread.Sleep(5000);
                    DisplayCraneThreadInfo += "\r\n获得吊车搬运指令应答";
                    string sql2 = "INSERT INTO instruction(start_point,end_point,send_time,socket_code,content,task_id)VALUES(@start_point,@end_point,@send_time,@socket_code,@content,@task_id);";
                    SqlParameter[] sqlParameters2 = new SqlParameter[] {
                                        new SqlParameter("@start_point",instruction.Start_point),
                                        new SqlParameter("@end_point",instruction.End_point),
                                        new SqlParameter("@send_time",DateTime.Now),
                                        new SqlParameter("@socket_code",result.Head.ToString() +
                                                                        result.EntranceAndExit.ToString() +
                                                                        taskQueue.End_point.Replace("-", "") +
                                                                        result.Code +
                                                                        result.SendOrAnswer),
                                        new SqlParameter("@content",result.Instructions),
                                        new SqlParameter("@task_id",taskQueue.Id)
                        };
                    if (DbHelper.ExcuteSQL(sql2, sqlParameters2) > 0)
                    {
                        Thread.Sleep(5000);
                        DisplayCraneThreadInfo += "\r\n询问吊车是否搬运完成";
                        electronicMessage = new ElectronicMessage();
                        electronicMessage.Type = result.Type;
                        electronicMessage.Instructions = "吊车搬运完成指令";
                        electronicMessage.EntranceAndExit = result.EntranceAndExit;
                        electronicMessage.Head = 103;
                        electronicMessage.Code = taskQueue.Goods_code.Replace("-", "");
                        electronicMessage.SendOrAnswer = "01";
                        DataSet ds3 = DbHelper.GetDataSet("SELECT * FROM instruction WHERE task_id = " + taskQueue.Id + " AND socket_code = '" + electronicMessage.Head.ToString() +
                                                                        electronicMessage.EntranceAndExit.ToString() +
                                                                        taskQueue.End_point.Replace("-", "") +
                                                                        electronicMessage.Code +
                                                                        electronicMessage.SendOrAnswer + "'");
                        if (ds3.Tables[0].Rows.Count == 0)
                        {

                            string sql3 = "INSERT INTO instruction(start_point,end_point,send_time,socket_code,content,task_id)VALUES(@start_point,@end_point,@send_time,@socket_code,@content,@task_id);";
                            SqlParameter[] sqlParameters3 = new SqlParameter[] {
                                        new SqlParameter("@start_point",instruction.Start_point),
                                        new SqlParameter("@end_point",instruction.End_point),
                                        new SqlParameter("@send_time",DateTime.Now),
                                        new SqlParameter("@socket_code",electronicMessage.Head.ToString() +
                                                                        electronicMessage.EntranceAndExit.ToString() +
                                                                        taskQueue.End_point.Replace("-", "") +
                                                                        electronicMessage.Code +
                                                                        electronicMessage.SendOrAnswer),
                                        new SqlParameter("@content",electronicMessage.Instructions),
                                        new SqlParameter("@task_id",taskQueue.Id)
                            };
                            if (DbHelper.ExcuteSQL(sql3, sqlParameters3) > 0)
                            {
                                GetInstructionListByTaskId(taskQueue.Id);
                                Thread.Sleep(5000);
                                DisplayCraneThreadInfo += "\r\n吊车应答搬运完成";
                                result = new ElectronicMessage();
                                result.Type = electronicMessage.Type;
                                result.Instructions = "吊车搬运完成应答";
                                result.EntranceAndExit = result.EntranceAndExit;
                                result.Head = 103;
                                result.Code = taskQueue.Goods_code.Replace("-", "");
                                result.SendOrAnswer = "02";
                                DataSet ds4 = DbHelper.GetDataSet("SELECT * FROM instruction WHERE task_id = " + taskQueue.Id + " AND socket_code = '" + result.Head.ToString() +
                                                                                result.EntranceAndExit.ToString() +
                                                                                taskQueue.End_point.Replace("-", "") +
                                                                                result.Code +
                                                                                result.SendOrAnswer + "'");
                                if (ds4.Tables[0].Rows.Count == 0)
                                {
                                    string sql4 = "INSERT INTO instruction(start_point,end_point,send_time,socket_code,content,task_id)VALUES(@start_point,@end_point,@send_time,@socket_code,@content,@task_id);";
                                    SqlParameter[] sqlParameters4 = new SqlParameter[] {
                                        new SqlParameter("@start_point",instruction.Start_point),
                                        new SqlParameter("@end_point",instruction.End_point),
                                        new SqlParameter("@send_time",DateTime.Now),
                                        new SqlParameter("@socket_code",result.Head.ToString() +
                                                                        result.EntranceAndExit.ToString() +
                                                                        taskQueue.End_point.Replace("-", "") +
                                                                        result.Code +
                                                                        result.SendOrAnswer),
                                        new SqlParameter("@content",result.Instructions),
                                        new SqlParameter("@task_id",taskQueue.Id)
                                    };
                                    if (DbHelper.ExcuteSQL(sql4, sqlParameters4) > 0)
                                    {
                                        GetInstructionListByTaskId(taskQueue.Id);
                  
                                        return result;
                                        
                                       
                                    }
                                }

                            }
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 根据任务主键获取对应的指令列表，按照发送时间排序。
        /// </summary>
        /// <param name="task_id"></param>
        private void GetInstructionListByTaskId(Int32 task_id)
        {
            //加载指令列表
            DataTable dataTable = DbHelper.GetTable("SELECT * FROM instruction WHERE task_id = " + task_id + "  ORDER BY send_time");
            List<Instruction> instructionListFromDataBase = new List<Instruction>();
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                Instruction instruction = new Instruction();
                DataRow dataRow = dataTable.Rows[i];
                if (dataRow["id"] != DBNull.Value)
                {
                    instruction.Id = Convert.ToInt32(dataRow["id"]);
                }
                if (dataRow["start_point"] != DBNull.Value)
                {
                    instruction.Start_point = Convert.ToInt32(dataRow["start_point"]);
                }
                if (dataRow["end_point"] != DBNull.Value)
                {
                    instruction.End_point = Convert.ToInt32(dataRow["end_point"]);
                }
                if (dataRow["send_time"] != DBNull.Value)
                {
                    instruction.Send_time = Convert.ToDateTime(dataRow["send_time"].ToString());
                }
                if (dataRow["socket_code"] != DBNull.Value)
                {
                    instruction.Socket_code = dataRow["socket_code"].ToString();
                }
                if (dataRow["content"] != DBNull.Value)
                {
                    instruction.Content = dataRow["content"].ToString();
                }
                if (dataRow["task_id"] != DBNull.Value)
                {
                    instruction.Task_id = Convert.ToInt32(dataRow["task_id"]);
                }
                instruction.OrderNo = i + 1;
                instructionListFromDataBase.Add(instruction);
            }
            this.InstructionList = instructionListFromDataBase;
        }



    }
}
